package sslsockets;

import java.io.BufferedReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyManagementException;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;


public class SSLSocketClient {
	
	static String clientTrustKeyStoreFile = "src/registration/config/Trusted"; 
	
	static public void main(String[] args){
		
		try{
			
			TrustManager tm = new X509TrustManager() {
			    public void checkClientTrusted(X509Certificate[] chain,
			                    String authType)
			                    throws CertificateException {
			        //do nothing, you're the client
			    }
	
			    public X509Certificate[] getAcceptedIssuers() {
			        //also only relevant for servers
			    	return null;
			    }
	
			    public void checkServerTrusted(X509Certificate[] chain,
			                    String authType)
			                    throws CertificateException {
			        /* chain[chain.length -1] is the candidate for the
			         * root certificate. 
			         * Look it up to see whether it's in your list.
			         * If not, ask the user for permission to add it.
			         * If not granted, reject.
			         * Validate the chain using CertPathValidator and 
			         * your list of trusted roots.
			         */
			    	try{
			    		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
			    		FileInputStream in = new FileInputStream(clientTrustKeyStoreFile);
			    		ks.load(in, "".toCharArray());
			    		Certificate trusted = ks.getCertificate("PKW");
			    		in.close();
				    	for (Certificate cert : chain){
				    		try{
				    			cert.verify(trusted.getPublicKey());
				    			System.out.println("Client: Certificates do match!!");
				    		} catch (SignatureException ex){
				    			System.out.println("Client: Certificates don't match");
				    		}
				    	}
			    	} catch (Exception e){
			    		e.printStackTrace();
			    	}
			    }
			};
			
			SSLContext ctx = SSLContext.getInstance("TLS");
			TrustManager[] tmChain = {tm};
			ctx.init(null, tmChain, null);
			
			SSLSocketFactory fac = ctx.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket)fac.createSocket("localhost",1234);
			
    		for (String s:sslSocket.getSupportedCipherSuites()){
			System.out.println(s);
    		}
    		String[] cipherSuites = sslSocket.getSupportedCipherSuites();
    		sslSocket.setEnabledCipherSuites(cipherSuites);
			
			sslSocket.setNeedClientAuth(false);
			
            OutputStream out = sslSocket.getOutputStream();
            ObjectOutputStream oout = new ObjectOutputStream( out );
            oout.writeObject( "sdsadasdwq" );
            InputStream in = sslSocket.getInputStream();
            ObjectInputStream oin = new ObjectInputStream( in );
            Object received;
            try
            {
                received = oin.readObject();
            }
            catch( Exception e )
            {
                return; // TODO server nie odeslal certyfikatu i gowno - cytuje
                        // michala
            }
            if (received instanceof String){
            	System.out.println("client: " + (String)received);
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
